#ifndef __TCUCOMMUNICATION_H__
#define __TCUCOMMUNICATION_H__
#include "stm32f7xx_hal.h"
#include "lwip.h"
#include "exceptionProc.h"

#define __UDP_CONNECT__
#define SYNC 			0xFF
#define FRAME_HEADER	"IES"


typedef void (*tcufunctPtr)(uint8_t );

typedef struct 
{
	uint8_t eventId;						//event id
	uint8_t always; 						//frame sending times   if value == 0xff always send
	uint8_t reserved; 						//reserved
	uint16_t reserved1;    					//reserved
	uint16_t framePeriod; 					//send data frame period
	uint16_t frameTimeOut;					//send frame time out
	tcufunctPtr tcuFrameSendFunct;			//send data function
	tcufunctPtr tcuCallbackFunct;			//Function call back
}tcuCommunicationDef;


typedef struct
{
	uint8_t sendEnable; 					//send enable flag
	uint8_t sendTimes;						//number of sending times
}tcuCommSendCtrlDef;

typedef void (*tcuTimeoutFuncPtr)(uint8_t,uint8_t);
typedef struct
{
	uint8_t eventId;
	uint8_t timingEnable;
	uint8_t timeoutFlag;
	uint8_t rcv;
	uint16_t frameTimeout;
	tcuTimeoutFuncPtr tcuTimeoutCallbackFunc;
}tcuCommRcvResDef;

/******************************************************** frame type defined start *********************************************/
typedef enum 
{
	STATUS_MSG_E = 0,
	HEART_BEAT_E,
	CREMOTE_MSG_E,
}tcuMsgLoopFrameE;

typedef enum
{
	DEBUG_MSG_E = 0,
	CALIBRATION_E,
	MODULE_MSG_E,	
}tcuDebugFrameResE;

typedef enum
{
	START_CHARGING_RESPONSE_E = 0,
	STOP_CHARGING_RESPONSE_E,
	POWER_REGULATION_RESPONSE_E,
	PARAMETER_SET_RESPONSE_E,
	PARAMETER_QUERY_RESPONSE_E,
	CHARGING_RESPONSE_MAX	
}tcuChargingFrameResE;

typedef enum
{
	START_CHARGING_REQUEST_E = 0,
	STOP_CHARGING_REQUEST_E,
	REMOTE_PILE_REQUEST_E,
	REMOTE_EV_REQUEST_E,
	ERROR_REQUEST_E,
	CHARGING_REQUEST_MAX	
}tcuChargingFrameReqE;

typedef enum
{
	T_START_FINISH_RES_E = 0,
	T_STOP_FINISH_RES_E,
	T_HEARTBEAT_E
}tcuRcvResMsgE;
/******************************************************** frame type defined end ***********************************************/

#pragma pack(1)
/********************************************************* start charging start ************************************************/
typedef struct 
{
	uint8_t connectorId;
	uint8_t loadSwitch;
	uint8_t startMethod;
	uint8_t doubleConnectorStatus;
	uint16_t targetVol;
	uint16_t targetCur;
}startChargingRcv;

typedef struct 
{
	uint8_t loadSwitch;
	uint8_t ackFlag;
	uint8_t failedReason;
	uint8_t startMethod;
	uint8_t reserved;
}startChargingSend;

typedef enum
{
	LOADSWITCHOPEN = 1,
	LOADSWITCHCLOSE
}loadSwitchStatusE;

typedef enum
{
	NORMALSTART = 0,
	IMMEDIATELY,
	V2GDISCHARGING = 0xFE,
	MANUALCHARGING	
}startMethodCtlE;

typedef enum
{
	DOUBLECONNECTORENABLE = 0,
	DOUBLECONNECTORDISABLE,
	
}doubleConnectorStatusE;

typedef enum
{
	CHARGESUCCESS = 0,
	CHARGEFAULT,
	
}chargingstatusE;
/********************************************************* start charging end *************************************************/


/**************************************************** start charging finished start ********************************************/
typedef struct 
{
	uint8_t loadSwitch;
	uint8_t ackFlag;
	uint8_t failedReason;
	uint8_t pileBmsProtocol[3];
	uint8_t bmsPileProtocol[3];
	uint8_t handShakeResult;
	uint8_t batteryType;
	uint8_t bmsMaxTemp;
	uint16_t bmsMaxVoltage;
	uint16_t bmsSingleMaxVoltage;
	uint16_t bmsMaxCurrent;
	uint16_t bmsRatedVoltage;
	uint16_t bmsCurrentVoltage;
	uint16_t bmsRatedCapacity;	
	uint16_t bmsNormalCapacity;
	uint16_t bmsSoc;	
	uint16_t pileMaxVoltage;
	uint16_t pileMinVoltage;
	uint16_t pileMaxCurrent;
	uint16_t pileMinCurrent;
	uint8_t vinEvccId[17];
	uint8_t bmsReady;	
	uint8_t pileReady;	
}startChargingFinishSend;

typedef struct 
{
	uint8_t connectorId;
	uint8_t loadSwitch;
	uint8_t ackFlag;
}startChargingFinishRcv;


typedef enum
{
	HANDSHAKESUCCESS = 0,
	HANDSHAKEFAILED	
}handShakeStatusE;

typedef enum
{
	LEADACIDBATTERY = 0x01,
	NICKELHYDROGEN_BATTERY,
	LITHIUM_IRON_HOSHATE_BATTERY,
	LITHIUM_MANGANESE_OXIDE_BATTERY,
	LITHIUM_COBALTOXIDE_BATTERY,
	TERNARY_MATERIAL_BATTERY,
	POLYMER_LITHIUMION_BATTERY,
	LITHIUM_TITANATE_BATTERY,
	OTHER_BATTERIES
}batteryTypeE;

typedef enum
{
	CHARGING_UNREADY = 0x00,
	CHARGING_READY = 0xAA
}chargingReadyStatusE;
/******************************************************* start charging finished end ********************************************/


/********************************************************** stop charging start ************************************************/

typedef struct 
{
	uint8_t ackFlag;
}stopChargingSnd;

typedef struct 
{
	uint8_t connectorId;
	uint8_t stopReason;
	uint8_t faultCode;	
}stopChargingRcv;

typedef enum
{
	NORMAL_STOP = 0,
	TCU_FAULT_STOP,
	CCU_FAULT_STOP
}stopReasonE;

typedef enum
{
	TCU_NORMAL_STOP= 0,
	TCU_CCU_COMM_STOP,
	READER_COMM_STOP,
	METER_COMM_STOP,
	ESAM_FAULT_STOP,
	ESUM_CRC_ERR_STOP,
	TCU_OTHER_STOP,
}faultCodeE;

typedef enum
{
	ACHIEVE_TARGET_SOC = 0x00,
	NOT_ACHIEVE_TARGET_SOC,
}socStatusE;
/******************************************************* stop charging end ****************************************************/



/***************************************************** stop charging finish start ********************************************/
typedef struct 
{
	uint8_t stopReason;
	uint8_t ackFlag;
	uint8_t socStatus;	
}stopChargingFinishSnd;

typedef struct 
{
	uint8_t connectorId;
	uint8_t stopReason;
	uint8_t ackFlag;	
}stopChargingFinishRcv;

/*************************************************** stop charging finish end ************************************************/


/******************************************************** heartbeat start ****************************************************/
typedef struct 
{
	uint8_t count;
	uint8_t tcuHeartbeatStatus;
	uint8_t pileStatus;
	uint8_t connectorStatus;
}heartbeatSnd;

typedef struct 
{
	uint8_t connectorId;
	uint8_t count;
	uint8_t ccuHeartbeatStatus;	
	uint8_t powerAllocation;	
	uint8_t doubleConnectorStatus;
}heartBeatRcv;

typedef enum
{
	HEARTBEAT_STATUS_NORMAL = 0x00,
	HEARTBEAT_STATUS_TIMEOUT,	
}heartbeatStatusE;

typedef enum
{
	CHARGING_DISABLE = 0x01,
	CHARGING_ENABLE,
}pileStatusE;

typedef enum
{
	CONNECTOR_AVAILABLE = 0x00,
	CONNECTOR_UNAVAILABLE,
	CONNECTOR_DISABLE,
}connectorAvailableE;

typedef enum
{
	NEED_ALLOCATION = 0,
	NORMAL_ALLOCATION,
	SUPPLEMENT_ALLOCATION,
	DOUBLE_CONNECOT_CHARGING,
	OTHER_ALLOCATION	
}powerAllocationE;
/************************************************************ heart beat end **************************************************/


/****************************************************** power regulation start ************************************************/
typedef struct 
{
	uint8_t powerRegulationCmd;
	uint16_t powerValue;	
	uint8_t ackFlag;
	uint8_t failedReason;
}powerRegulationSnd;

typedef struct 
{
	uint8_t connectorId;
	uint8_t powerRegulationCmd;
	uint16_t powerValue;	
	uint8_t saveValueFlash;
}powerRegulationRcv;

typedef enum
{
	ABSOLUTE_VALUE_POWER = 0x01,
	PERCENTAGE_POWER
	
}powerRegulationCmdE;

/***************************************************** power regulation end ***************************************************/



/*************************************************** remote information start *************************************************/
typedef struct 
{
	uint8_t connectorStatus;
	uint8_t totalFault;
	uint8_t totalWarn;
	uint8_t emergencyStop;
	uint8_t smokeSensorFault;
	uint8_t acBreakFault;
	uint8_t dcRelayFault;
	uint8_t dcFuseFault;
	uint8_t electronicLockFault;
	uint8_t fanFault;
	uint8_t SPDFault;
	uint8_t insulationFault;
	uint8_t battPolarFault;
	uint8_t cpVoltageFault;
	uint8_t pileOverTempFault;
	uint8_t connectorOverTempFault;
	uint8_t connectorBackWarn;
	uint8_t acInputOverVolFault;
	uint8_t acInputUnderVolFault;
	uint8_t dcOutputOverVol;
	uint8_t dcOutputUnderVol;
	uint8_t dcOutputOverCur;
	uint8_t powerModuleFault;
	uint8_t moduleAcInputFault;
	uint8_t moduleInputOverVol;
	uint8_t moduleInputUnderVol;
	uint8_t moduleInputMissPhase;
	uint8_t moduleOutputShort;
	uint8_t moduleOutputOverCur;
	uint8_t moduleOutputOverVol;
	uint8_t moduleOutputUnderVol;
	uint8_t moduleOverTemp;
	uint8_t moduleCommFault;
	uint8_t moduleFanFault;
	uint8_t evConnectStatus;
	uint8_t pileHolderStatus;
	uint8_t electronicLockStatus;
	uint8_t dcRelayStatus;
	uint8_t accessCtrlFault;
	uint8_t dcRealyWeldFault;
	uint8_t insulationWarn;
	uint8_t leakageCircuitFault;
	uint8_t pileOverTempWarn;
	uint8_t connectorOverTempWarn;
	uint8_t acRelayNoActionFault;
	uint8_t acRelayWeldFault;
	uint8_t parallelRelayNoAction;
	uint8_t parallelRelayWeldFault;
	uint8_t parallelRelayStatus;	
	uint8_t waterImmersionSwitch;
	uint8_t cabinetSmokeSensorFault;
	uint8_t reserved1;
	uint8_t reserved2;
	uint8_t reserved3;
}remoteInformation;

typedef enum
{
	CONNECTOR_IDLE = 0x00,		//no EV connected
	CONNECTOR_WORKING,			//charging th EV
	CONNECTOR_CHARGING_FINISH,	//charging ended but the connector is still connected
	CONNECTOR_CHARGING_PAUSE	//not supported now
}connectorStatusE;
/*************************************************** remote information end ***************************************************/


/***************************************************** remote measure start ***************************************************/
typedef struct 
{
	uint16_t outputVoltage;
	uint16_t outputCurrent;
	uint8_t  soc;
	uint8_t  ambientTemp;
	uint16_t cpVoltage;
	uint16_t  requestVoltage;
	uint16_t  requestCurrent;
	uint8_t  chargingMode;
	uint16_t  bmsChargingVoltage;
	uint16_t  bmsChargingCurrent;
	uint16_t  bmsRemainTime;
	uint8_t  connectorTempN;
	uint8_t  connectorTempP;
	uint8_t  connectorTempHead;
	uint8_t  connectorTempCable;
	uint8_t  meterCurReadData[4];
	uint8_t  reserved[4];	
}measureEvInfo;

typedef enum
{
	CONSTANT_VOLTAGE_CHARGING = 0x01,
	CONSTANT_CURRENT_CHARGING
}ChargingModeE;
typedef struct 
{
	uint8_t cpVoltage;
	uint16_t busVoltage;
	uint16_t batVoltage;
	uint8_t chargingStage;
	uint16_t setModuleVoltage;
	uint16_t setModuleCurrent;
	uint16_t moduleOutputVoltage;
	uint16_t moduleOutputCurrent;
	uint16_t insulationResPositive;
	uint16_t insulationResNegative;
	uint8_t  moduleRunNum;
	uint16_t reserved;
}measurePileInfo;
/***************************************************** remote measure end *****************************************************/


/***************************************************** pile status start ******************************************************/
typedef struct 
{
	uint8_t pileStatusStep;
}pileStatusInformation;


typedef enum
{
	EV_DISCONNECTED = 0,
	EV_CONNECTED,
	HANDSHAKE_STATUS,
	SERVICE_DISCOVERY,
	PARAMENTER_CONFIG,
	INSULATION_DETECTION,
	PRECHARGE,
	RELAY_CLOSE_STEP,
	CURRENT_DEMAND,
	WELD_DETECTION,
	STOP_CHARGING,
	CHARGING_FINISH
	
}pileStatusStepE;
/******************************************************** pile status end *****************************************************/


/***************************************************** error frame start ******************************************************/
typedef struct 
{
	uint8_t chargingStartFinishTimeout;
	uint8_t chargingStopFinishTimeout;
	uint8_t heartbeatTimeout;
}pileRcvTimeoutSend;

typedef struct 
{
	uint8_t connectorId;
	uint8_t rsv;
	uint8_t chargingParameterTimeout;
	uint8_t chargingStartCmdTimeout;
	uint8_t chargingStartFinishTimeout;
	uint8_t ChargingStopCmdTimeout;
	uint8_t ChargingStopFinishTimeout;
	uint8_t autoTimeTimeout;
	uint8_t chargingSrvStartStopTimeout;
	uint8_t electronicLockCtrlTimeout;
	uint8_t regulationTimeout;
	uint8_t paramQueryTimeout;
	uint8_t remoteMessageTimeout;
	uint8_t remoteMeasureTimeout;
	uint8_t downloadTimeout;
}pileRcvTimeoutRcv;
/****************************************************** error frame end ******************************************************/



/*************************************************** config message query start **********************************************/
//tcu get parameter from ccu.??? 
typedef struct
{
	uint8_t pileStaus;
	uint8_t connectorStaus;
	uint8_t chargeMethod;
	uint8_t loadSwitch;
	uint8_t chargeStatus;
	uint8_t failedReason;
	uint8_t startType;
	uint8_t pileBmsProtocal[3];
	uint8_t bmsPileProtocal[3];
	uint8_t handShakeResult;
	uint8_t batteryType;
	uint8_t BmsMaxTemp;
	uint8_t bmsMaxVoltage[2];
	uint8_t bmsSignalVoltage[2]; 
	uint8_t bmsMaxCurrent[2];
	uint8_t bmsRatedVoltage[2];
	uint8_t bmsCurrentVoltage[2];
	uint8_t bmsRateCapacity[2];	
	uint8_t bmsNormalCapacity[2];
	uint8_t bmsSoc[2];
	uint8_t pileMaxVoltage[2];
	uint8_t pileMinVoltage[2];
	uint8_t pileMaxCurrent[2];
	uint8_t pileMinCurrent[2];
	uint8_t vinEvccId[17];
	uint8_t bmsStatus;	
}tcuParameterStatus;

//config message quere frame .  id 61
typedef struct
{
	uint8_t factorNum[4];
	uint8_t pileDevType[2];
	uint8_t supportedProtocol;
	uint8_t pileNum[12];
	uint8_t ccuHardVersion[2];
	uint8_t ccuSoftVersion[3];
	uint8_t ccuSoftData[4];
	uint16_t maxVoltage;
	uint16_t minVoltage;
	uint16_t maxCurrent;
	uint16_t minCurrent;
	
}tcuParameterQuery;

typedef enum{
//	DIN70121 = 0x01,	//already exist
	ISO15118 = 0x02,
	DIN70121_ISO15118,
}SupportedProtocolE;
/************************************************** config message query end **************************************************/


/*************************************************** config message set start *************************************************/
//charging pile config message download
typedef struct
{
	uint8_t ackFlag;
}tcuParameterConfigSnd;

typedef struct
{
	uint8_t connectorId;
	uint8_t acOverVolLimit;
	uint8_t acUnderVolLimit;
	uint8_t connectorBrand;
	uint8_t connectorType;
	uint8_t connectorNum;
	uint8_t connectorRatedCurrent[2];
	uint8_t connectorMaxCurrent[2];
	uint8_t moduleBrand;
	uint8_t modulePower;
	uint8_t moduleNum;
	uint8_t moduleGroup;
	uint8_t tcuBrand;
	uint8_t ccuNum;
	uint8_t currentDiverter;
	uint8_t canConfig;
	uint8_t electronicLock;
	uint8_t accessCtrlSwitch;
	uint8_t acContactCfg;
	uint8_t dcRelayCfg;
	uint8_t smokeSensorCfg;
	uint8_t supplyPowerChangeCfg;
	uint8_t pcuBoardCfg;
	uint8_t meterCfg;
	uint8_t currentSample;
	uint8_t	connectorTempChk;
	uint8_t isoMonitorSelect;
	uint8_t bmsVolMonitor;
	uint8_t isoFaultValue[2];
	uint8_t isoWarnValue[2];
	uint8_t connectorOverTempProtectVal[2];
	uint8_t connectorOverTempFaultVal[2];
	uint8_t connectorOverTempWarnVal[2];
	uint8_t pileMaxVoltage[2];
	uint8_t pileMinVoltage[2];
	uint8_t pileMaxCurrent[2];
	uint8_t pileMinCurrent[2];
	uint8_t pileRatedCurrent[2];
	uint8_t ccuDebugSwitch;
	uint8_t pileMaxPower[2];
	uint8_t relayType;
	uint8_t parallelRelayCfg;
	uint8_t acBreakCfg;
	uint8_t supplyPowerCfg;
	uint8_t PileType;
	uint8_t reserved[7];
}tcuParameterConfigRcv;

typedef enum
{
	POSITIVE_FEEDBACK = 0,
	NEGATIVE_FEEDBACK,
	DISABLE_FEEDBACK
}generalFeedbackE;

typedef enum
{
	LOCK_POSITIVE_FEEDBACK = 0,
	LOCK_NEGATIVE_FEEDBACK,
	LOCK_DISABLE_FEEDBACK,
	NO_LOCK_NO_FEEDBACK,
}electronicLockFeedbackE;

typedef enum
{
	AC_POSITIVE_FEEDBACK = 0,
	AC_NEGATIVE_FEEDBACK,
	AC_DISABLE_FEEDBACK,
	NO_AC,
	NO_AC_MODULE_LOW_CONSUMP,
}acFeedbackE;

typedef enum
{
	CONFIG_EXIST = 0x00,
	CONFIG_NOT_EXIST
}configStatusE;

typedef enum
{
	DEBUG_SWITCH_OFF = 0x00,
	DEBUG_SWITCH_ON
}ccuDebugStatusE;
/**************************************************** config message set end *************************************************/

/****************************************************** calibration start ****************************************************/
typedef struct 
{
	uint8_t calibrationType;
	uint8_t reserved1;
	uint8_t status;
	uint8_t reserved2[5];
}calibratoinSnd;

typedef struct 
{
	uint8_t connectorId;
	uint8_t calibrationType;
	uint8_t pushButtonCalibration;
	uint32_t calibrationData;
	uint8_t reserved[2];
}calibratoinRcv;

typedef enum{
	OUTPUT_VOLTAGE_CALIBRATION = 0x01,
	OUTPUT_CURRENT_CALIBRATION,
	CP_VOLTAGE_CALIBRATION,
	TEMPERTURE_CALIBRATION
}calibrationTypeE;


typedef enum{
	PARAMETER_FIRST_TARGET_PUSHBUTTON = 0x01,
	PARAMETER_FIRST_ACTUAL_PUSHBUTTON,
	PARAMETER_SECOND_TARGET_PUSHBUTTON,
	PARAMETER_SECOND_ACTUAL_PUSHBUTTON,
	AUTO_PUSHBUTTON,
	STOP_PUSHBUTTON,
	OTHER_PUSHBUTTON,	
}calibrationSelectE;



/******************************************************** calibration end ****************************************************/


/******************************************************** debug start ********************************************************/
typedef struct 
{
	uint8_t connectorId;
	uint8_t fanCtrl;
	uint8_t dcRelay1;
	uint8_t dcRelay2;
	uint8_t dcRelay3;
	uint8_t parallelRelay;
	uint8_t acRelay;
	uint8_t standLed;
	uint8_t chargingLed;
	uint8_t faultLed;
	uint8_t insulationRelayN;
	uint8_t insulationRelayG;
}debugRcv;

typedef struct 
{
	uint8_t supplyPower;
	uint8_t powerVolSwitch;
	uint8_t electronicLock;
	uint8_t dcRelay;
	uint8_t parallelRelay;
	uint8_t acRelay;
	uint8_t surgeProtector;
	uint8_t doorSwitch;
	uint8_t emergencyStopSwitch;
	uint8_t waterImmersionSwitch;
	uint8_t smokeWarn;
}debugSnd;

typedef enum
{
	RELAY_CLOSE = 0x01,
	RELAY_OPEN
}relayStatusE;
/***********************************************************debug end*********************************************************/



/**************************************************** power module message start *********************************************/
typedef struct 
{
	uint8_t connectorId;
	uint8_t powerModuleNum;
	uint8_t reserved[6];
}powerMsgQueryRcv;

typedef struct 
{
	uint8_t powerModuleNum;
	uint8_t ccuNumber;
	uint8_t moduleFault;
	uint8_t moudleProtect;
	uint8_t moduleInputFault;
	uint8_t moduleInputOverVol;
	uint8_t moduleInputUnderVol;
	uint8_t moduleInputMissPhase;
	uint8_t moduleOutputOverVol;
	uint8_t moduleOutputUnderVol;
	uint8_t moduleOutputShort;
	uint8_t moduleFanFault;
	uint8_t moduleOverTemp;
	uint8_t moduleCommFault;
	uint8_t reserved;
	uint16_t moduleOutputVol;
	uint16_t moduleOutputCur;
	uint8_t moduleComSuccessRate;
	
}powerMsgQuerySnd;
/*************************************************** power module message end *************************************************/

typedef struct 
{
	//always send, timer set flag
	uint8_t heartBeatFlag;
	uint8_t remoteMsgFlag;
	uint8_t pileStatusFlag;
	
	uint8_t startChargingFinishReqFlag;
	uint8_t stopChargingFinishReqFlag;
	//entry current demand send 
	uint8_t remoteMeasure1Flag;
	uint8_t remoteMeasure2Flag;
	uint8_t errorFrameFlag;
	
	uint8_t debugResFlag;
	uint8_t calibrationResFlag;
	uint8_t moduleResFlag;
	
	//response data frame
	uint8_t startChargingResFlag;
	uint8_t stopChargingResFlag;
	uint8_t powerAdjustResFlag;
	uint8_t parementerSetResFlag;
	uint8_t parementerQueryResFlag;
}dataFrameStatus;

#pragma pack()

/************************************************* Variables ******************************************************/


/************************************************** function ******************************************************/
void tcuLogicInit(void);			//called by main.c
void tcuCommunicationEntry(void);	//called by main.c

void rcvDataAnalysis(void);			//called by tcuLogicProcess.c
void tcuCommunicationLoop(void);	//called by tcuLogicProcess.c
void entryhCharingLoop(void);		//called by tcuLogicProcess.c
#endif   // __TCUCOMMUNICATION_H__

